/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package VideoStreaming;

/**
 *
 * @author naveen
 */
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Hashtable;

import javax.microedition.io.Connector;
import javax.microedition.io.ContentConnection;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Item;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import javax.microedition.media.control.VideoControl;
import net.jxta.j2me.PeerNetwork;
import net.jxta.j2me.Message;
import net.jxta.j2me.Element;

public class Stream {

    private static final boolean DEBUG = true;
    int chunks;
    private PeerNetwork peer = null;
    private Hashtable mateIDS = new Hashtable();
    private byte[] state = new byte[0];
    private String id;
    private byte[][] chunksdata;
    private boolean stopPolling = false;
    private boolean sendPending = false;
    private static final boolean QUANTIFY = true;
    byte videoData[];
    Message msg;
    
    

    public Stream(){
        
    }
    /*Stream(String id) {
        throw new UnsupportedOperationException("Not yet implemented");
    }*/

    public boolean isSendPending() {
        return sendPending;
    }

    public void setSendPending(boolean sendPending) {
        this.sendPending = sendPending;
    }

    public byte[] getState() {
        return state;
    }

    public void setState(byte[] state) {
        this.state = state;
    }

    public boolean isStopPolling() {
        return stopPolling;
    }

    public void setStopPolling(boolean stopPolling) {
        this.stopPolling = stopPolling;
    }

    public Hashtable getMateIDS() {
        return mateIDS;
    }

    public void setMateIDS(Hashtable mateIDS) {
        this.mateIDS = mateIDS;
    }

    public PeerNetwork getPeer() {
        return peer;
    }

    public void setPeer(PeerNetwork peer) {
        this.peer = peer;
    }

    public static boolean isDEBUG() {
        return DEBUG;
    }

    public static boolean isQUANTIFY() {
        return QUANTIFY;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

  

    /**
     * function converting video to bytes
     * @param videourl
     * @return video in bytes[]
     */
    public byte[] videotobytearray(String videourl) {
        
        try {
            FileConnection connection = (FileConnection) Connector.open(videourl);
            ByteArrayOutputStream bStrm = null;
            System.out.println(connection.totalSize());
            DataInputStream iStrm = connection.openDataInputStream();
            int length = (int)
                    connection.fileSize();
            if (length != -1) {
                videoData = new byte[length];
                iStrm.readFully(videoData);
            } else {
                bStrm = new ByteArrayOutputStream();
                int ch;
                while ((ch = iStrm.read()) != -1) {
                    bStrm.write(ch);
                }
                videoData = bStrm.toByteArray();
                bStrm.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return videoData;
    }

    /**
     * function for preparing the message to be sent     
     * @param numberHits
     * @param Videourl
     * @param connected
     * @return msg of Message type
     */
    public Message send(int numberHits, String Videourl) {
        Peers peerobj = new Peers();
        byte[] videoData = videotobytearray(Videourl);
        int length = videoData.length;

        if (numberHits == 1) {

            Element[] elm = new Element[3];
            elm[0] = new Element("VideoReply", peerobj.getName().getBytes(),null,null );
           // elm[1] = new Element("JxmeVideoID", getId().getBytes(),null, null);
            elm[1] = new Element("JxmeVideo",videoData,null, null);
            elm[2] = new Element("GrpName",
                    "NetPeerGroup".getBytes(),
                    null, null);
            msg = new Message(elm);
        } else {
            int rem, i;
            chunks = (length / numberHits);
            rem = (length % numberHits);
            chunksdata = videochunks(chunks, rem, videoData, numberHits);
            Element[] elm = new Element[chunks + 2];
            elm[0] = new Element("JxmeVideo", getId().getBytes(),
                    null, null);
            for (i = 0; i < chunksdata.length; i++) {

                String VideoHeader = Integer.toString(i);
                elm[i + 1] = new Element(VideoHeader,
                        chunksdata[i],
                        null, null);

            }
            //writing the last element name with group name
            elm[i + 1] = new Element("GrpName", "NetPeerGroup".getBytes(), null, null);
            /*elm[2] = new Element("GrpName",
            "NetPeerGroup".getBytes(),
            null, null);*/
            msg = new Message(elm);
        }
        return msg;
    }

    /**
     * function to make the video chunks
     * @param chunks
     * @param rem
     * @param videoData
     * @param numberHits
     * @return the video chunks in byte array[][]
     */
    private byte[][] videochunks(int chunks, int rem, byte[] videoData, int numberHits) {
        int i = 1;
        int j = 0;
        int numChunks = 0;
        byte chunksdata[][] = new byte[numberHits][];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos);
        while (i <= numberHits) {
            try {
                dos.write(videoData, (chunks * j), chunks);
                chunksdata[numChunks] = baos.toByteArray();
                ++numChunks;
                j = i;
                i++;
                baos.flush();
                dos.close();
                baos.close();
                baos = new ByteArrayOutputStream();
                dos = new DataOutputStream(baos);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        if (rem != 0) {
            try {
                dos.write(videoData, (chunks * chunks), rem);
                chunksdata[numChunks] = baos.toByteArray();
                ++numChunks;
                j = i;
                i++;
                baos.flush();
                dos.close();
                baos.close();
                baos = new ByteArrayOutputStream();
                dos = new DataOutputStream(baos);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return chunksdata;
    }

    private void showAlert(String title, String message, AlertType type) {
        Alert alert = new Alert(title, message, null, type);

    }
}
